package com.blue.integration.serve.aliyun;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blue.core.http.HttpException;
import com.blue.core.util.FileUtil;
import com.blue.core.util.JsonUtil;
import com.blue.integration.serve.IdentityCard;
import com.blue.integration.serve.IdentityCardClient;
import com.blue.integration.serve.OcrException;


/**
 * 阿里云OCR身份证识别
 *
 * @author zhengjin
 * @since 1.0 2017年11月28日
 */
public class AliyunIdentityCardClient extends AbstractOcrClient implements IdentityCardClient
{
	private static Logger logger = LoggerFactory.getLogger(AliyunIdentityCardClient.class);

	public AliyunIdentityCardClient()
	{
	}

	@Override
	public IdentityCard ocr(IdentityCard.Side side, File file) throws OcrException
	{
		Assert.notNull(file, "身份证文件不能为空");
		try
		{
			FileInputStream fis = new FileInputStream(file);
			return this.ocr(side, fis);
		}
		catch (FileNotFoundException e)
		{
			throw new OcrException("身份证文件不存在：" + file.getAbsolutePath());
		}
	}

	@Override
	public IdentityCard ocr(IdentityCard.Side side, InputStream is) throws OcrException
	{
		Assert.notNull(side, "身份证正面或反面不能为空");
		Assert.notNull(is, "身份证文件输入流不能为空");

		String imgBase64 = null;
		try
		{
			imgBase64 = FileUtil.toBase64(is);
		}
		catch (IOException e)
		{
			logger.error("读取身份证文件失败：", e);
			throw new OcrException("读取身份证文件失败");
		}
		if (imgBase64 == null || imgBase64.isEmpty())
			throw new OcrException("读取身份证文件失败");

		Header authHeader = new BasicHeader("Authorization", "APPCODE " + appCode);
		Header acceptHeader = new BasicHeader("Accept", "application/json");
		Header contentTypeHeader = new BasicHeader("Content-Type", "application/json;charset=utf-8");

		JSONObject configObj = new JSONObject();
		configObj.put("side", side.toString().toLowerCase());
		JSONObject obj = new JSONObject();
		obj.put("image", new DataValueRequest(ID_TYPE, imgBase64));
		obj.put("configure", new DataValueRequest(ID_TYPE, configObj.toJSONString()));
		JSONArray inputArray = new JSONArray();
		inputArray.add(obj);
		JSONObject requestObj = new JSONObject();
		requestObj.put("inputs", inputArray);

		String json = requestObj.toJSONString();
		String result = null;
		try
		{
			logger.debug("参数：{}", json);
			result = httpInvoker.post(url, json, authHeader, acceptHeader, contentTypeHeader);
			logger.info("结果：{}", result);
		}
		catch (HttpException | IOException e)
		{
			logger.error("身份证识别失败：", e);
			throw new OcrException("身份证识别失败");
		}
		if (result == null || result.isEmpty())
			throw new OcrException("身份证识别失败");

		JSONObject rootObj = JSON.parseObject(result);
		JSONObject outputObj = rootObj.getJSONArray("outputs").getJSONObject(0);
		String resultJson = outputObj.getJSONObject("outputValue").getString("dataValue");
		AliyunIdCard idCard = JSON.parseObject(resultJson, AliyunIdCard.class);
		logger.debug("对象：{}", JsonUtil.encode(idCard));

		if (!idCard.isSuccess())
			throw new OcrException("身份证识别失败");

		IdentityCard card = idCard.toIdentityCard();
		card.setSide(side);
		logger.debug("对象：{}", JsonUtil.encode(card));

		return card;
	}

	@Override
	public void afterPropertiesSet() throws Exception
	{
		super.afterPropertiesSet();

		logger.info("初始化阿里云OCR身份证识别接口：{}", url);
	}

}
